<?php

declare(strict_types=1);

namespace ImiApp\ApiServer\Backend\Service\System;

use Imi\Bean\Annotation\Inherit;
use Imi\Config;
use ImiApp\ApiServer\Backend\Model\SoAttachment;
use ImiApp\ImiServer\AbstractModel;
use ImiApp\ImiServer\AbstractService;
use Imi\Bean\Annotation\Bean;
use ImiApp\ImiServer\Exception\ServiceException;
use Imi\Aop\Annotation\Inject;
use ImiApp\ImiServer\Service\Upload;
use Phpben\Imi\Auth\AuthManager;
use ImiApp\ApiServer\Api\Model\Attachment;



use Obs\ObsClient;
use Obs\ObsException;



use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
/**
 * @Inherit
 * @Bean("SystemAttachmentService")
 */
class AttachmentService extends AbstractService
{
    /**
     * @var string
     */
    public $model = SoAttachment::class;

    /**
     * @var string
     */
    public $model2 = Attachment::class;

    /**
     * Auth
     * @Inject(name=AuthManager::class,args={"backend"})
     */
    protected $auth;

    /**
     * @Inject(Upload::class)
     *
     * @var \ImiApp\ImiServer\Service\Upload
     */
    protected $upload;

    public function getParents(): array
    {
        $list = [['label' => '全部']];
        return array_merge($list, $this->model::query()->group("parent")->order('parent', 'desc')->fieldRaw("parent as label")->select()->getArray());
    }

    public function pull($files)
    {
        $file = $files['file'] ?? false;
        if (!$file) {
            $this->setError('未上传内容');
            return false;
        }
        $upload = $this->upload->pull($file);
        if (!$upload) {
            $this->setError($this->upload->getError());
            return false;
        }
        // var_dump('后台upload',$upload);
        $data = array_merge([
            'type' => Config::get('@app.beans.Upload.save'),
            'admin_id' => $this->auth->user()->id,
            'create_time' => time(),
        ], $upload);
        if ($row = $this->model::find(['filename' => $upload['filename']])) {
            $row->update($data);
        } else {
            $this->model::query()->insert($data);
        }


        //兼容fastadmin
        $sha1 = hash_file('sha1', '.' . $data['path']);
        $data = $this->compatible($data);
        if ($row2 = $this->model2::find(['sha1' => $sha1])) {
            $row2->update($data);
        } else {
            $this->model2::query()->insert($data);
        }

        $url = $this->oss($upload['path']);
        return ['url' => $upload['url'], 'filename' => $upload['filename'],'oss'=>$url];
    }

    public function _before_delete(&$ids)
    {
        foreach ($ids as $k => $id) {
            $path = $this->model::find($id);
            if (!$path) {
                unset($ids[$k]);
                continue;
            }
            $this->upload->delete($path->toArray()['path']);
        }
    }


    public function compatible($data)
    {

        $getimagesize = getimagesize('.' . $data['path']);
        $params = array(
            // 'admin_id'    => (int)session('admin.id'),
            // 'admin_id'     => $this->auth->user()->id,
            'admin_id' => 0,
            'user_id' => 0,
            'store_id' => 0,
            'filename'    => $data['filename'],
            'filesize'    => $data['size'],
            'imagewidth'  => $getimagesize[0],
            'imageheight' => $getimagesize[1],
            'imagetype'   => $data['extension'],
            'imageframes' => 0,
            'mimetype'    => $data['mediatype'],
            'url'         => str_replace('/public', '', $data['path']),
            'uploadtime'  => $data['create_time'],
            'storage'     => $data['type'],
            'sha1'        => hash_file('sha1', '.' . $data['path']),
            'extparam'    => '',
            'updatetime' => $data['create_time'],
            'createtime' => $data['create_time'],
        );
        var_dump($params);


        return $params;
    }



    public function oss($path)
    {
        $ak = 'M7EU11YWNEWIVNIV8ULR';
        $sk = 'fuqB8Q0Ut6WPyY0FvhwYDP8z8dEZRK6A6RXEzSC6';
        $endpoint = 'https://obs.cn-north-9.myhuaweicloud.com:443';
        $bucketName = 'pddds';
        
        $signature = 'obs';

        $q_path = substr($path,0,7);
        // var_dump($q_path);
        if($q_path=='/public'){
          $url_path = substr($path,7);
        //   var_dump($path);
        }else{
            $url_path = $path;
        }
        $objectKey = trim($url_path,'/');

        $obsClient = ObsClient::factory([
            'key' => $ak,
            'secret' => $sk,
            'endpoint' => $endpoint,
            'socket_timeout' => 30,
            'connect_timeout' => 10,
            'signature' => $signature
        ]);

        $sampleFilePath = '.' . $path;
        $this->createSampleFile($sampleFilePath);

        /*
        * Claim a post object request
        */
        $formParams = [];
        if (strcasecmp($signature, 'obs') === 0) {
            $formParams['x-obs-acl'] = ObsClient::AclPublicRead;
        } else {
            $formParams['acl'] = ObsClient::AclPublicRead;
        }
        $formParams['content-type'] = 'text/plain';

        $res = $obsClient->createPostSignature(['Bucket' => $bucketName, 'Key' => $objectKey, 'Expires' => 3600, 'FormParams' => $formParams]);

        $formParams['key'] = $objectKey;
        $formParams['policy'] = $res['Policy'];

        if (strcasecmp($signature, 'obs') === 0) {
            $formParams['Accesskeyid'] = $ak;
        } else {
            $formParams['AWSAccesskeyid'] = $ak;
        }

        $formParams['signature'] = $res['Signature'];


        // var_dump("Creating object in browser-based post way\n\n");
        $boundary = '9431149156168';

        $buffers = [];
        $contentLength = 0;

        /*
        * Construct form data
        */
        $buffer = [];
        $first = true;
        foreach ($formParams as $key => $val) {
            if (!$first) {
                $buffer[] = "\r\n";
            } else {
                $first = false;
            }

            $buffer[] = "--";
            $buffer[] = $boundary;
            $buffer[] = "\r\n";
            $buffer[] = "Content-Disposition: form-data; name=\"";
            $buffer[] = strval($key);
            $buffer[] = "\"\r\n\r\n";
            $buffer[] = strval($val);
        }

        $buffer = implode('', $buffer);
        $contentLength += strlen($buffer);
        $buffers[] = $buffer;

        /*
        * Construct file description
        */
        $buffer = [];

        $buffer[] = "\r\n";
        $buffer[] = "--";
        $buffer[] = $boundary;
        $buffer[] = "\r\n";
        $buffer[] = "Content-Disposition: form-data; name=\"file\"; filename=\"";
        $buffer[] = "myfile";
        $buffer[] = "\"\r\n";
        $buffer[] = "Content-Type: text/plain";
        $buffer[] = "\r\n\r\n";

        $buffer = implode('', $buffer);
        $contentLength += strlen($buffer);
        $buffers[] = $buffer;

        /*
        * Construct file data
        */
        $buffer = [];

        $fp = fopen($sampleFilePath, 'r');
        if ($fp) {
            while (!feof($fp)) {
                $buffer[] = fgetc($fp);
            }
            fclose($fp);
        }

        $buffer = implode('', $buffer);
        $contentLength += strlen($buffer);
        $buffers[] = $buffer;

        /*
        * Contruct end data
        */
        $buffer = [];
        $buffer[] = "\r\n--";
        $buffer[] = $boundary;
        $buffer[] = "--\r\n";

        $buffer = implode('', $buffer);
        $contentLength += strlen($buffer);
        $buffers[] = $buffer;


        $httpClient = new Client(['verify' => false]);
        $host = parse_url($endpoint)['host'];
        $host = $bucketName . '.' . $host;
        $url = 'https://' . $host . ':443';
        // var_dump('url', $url);
        $headers = ['Content-Length' => strval($contentLength), 'Content-Type' => 'multipart/form-data; boundary=' . $boundary];

        try {
            $response = $httpClient->request('POST', $url, ['body' => implode('', $buffers), 'headers' => $headers]);

            // var_dump('Post object successfully!');
            $response->getBody()->close();
        } catch (ClientException $ex) {
            // var_dump('Exception message:%s', $ex->getMessage());
        }

   
        return 'https://' . $host.'/'.$url_path;

        // $obsClient = ObsClient::factory([
        //     'key' => $ak,
        //     'secret' => $sk,
        //     'endpoint' => $endpoint,
        //     'socket_timeout' => 30,
        //     'connect_timeout' => 10
        // ]);

        // $obsClient->initLog([
        //     'FilePath' => './.runtime/logs', // 配置日志文件夹
        //     'FileName' => 'eSDK-OBS-PHP.log', // 配置日志文件名
        //     'MaxFiles' => 10, // 配置最大可保留的日志文件个数
        //     'Level' => 100  // 配置日志级别
        // ]);


    }

    public function deleteTempFile($sampleFilePath)
    {
        if (file_exists($sampleFilePath)) {
            unlink($sampleFilePath);
        };
    }


    public function createSampleFile($filePath)
    {
        if (file_exists($filePath)) {
            return;
        }
        $filePath = iconv('UTF-8', 'GBK', $filePath);
        if (is_string($filePath) && $filePath !== '') {
            $fp = null;
            $dir = dirname($filePath);
            try {
                if (!is_dir($dir)) {
                    mkdir($dir, 0755, true);
                }

                if (($fp = fopen($filePath, 'w'))) {

                    for ($i = 0; $i < 1000000; $i++) {
                        fwrite($fp, uniqid() . "\n");
                        fwrite($fp, uniqid() . "\n");
                        if ($i % 100 === 0) {
                            fflush($fp);
                        }
                    }
                }
            } finally {
                if ($fp) {
                    fclose($fp);
                }
            }
        }
    }
}